package cn.itcast.d_processVariable;

import java.io.InputStream;
import java.util.Date;
import java.util.List;
import java.util.zip.ZipInputStream;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.junit.Test;
/**
 * setVariable和setVariableLocal的区别
 * setVariable：
 * 		设置流程变量的时候，流程变量名称相同的时候，后一次的值替换前一次的值
 * 		，而且可以看到TASK_ID的字段不会存放任务ID的值
 * setVariableLocal：
 * 		设置流程变量的时候，针对当前活动的节点设置流程变量，如果一个流程中存在2个活动节点，
 * 		对每个活动节点都设置流程变量，即使流程变量的名称相同，后一次的版本的值也不会替换前一次版本的值，
 * 		它会使用不同的任务ID作为标识，存放2个流程变量值，而且可以看到TASK_ID的字段会存放任务ID的值
 */
public class ProcessVariablesTest {
	
	ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
	/**
	 * 部署流程定义（通过InputStrem）
	 * 1
	 */
	@Test
	public void deploymentProcessDefinition_stram(){
		InputStream ProcessInstanceBpmn=this.getClass().getClassLoader().getResourceAsStream("diagrams/ProcessInstanceTest.bpmn");
		InputStream ProcessInstancePng=this.getClass().getClassLoader().getResourceAsStream("diagrams/ProcessInstanceTest.png");
		
		Deployment deployment = processEngine.getRepositoryService()
		.createDeployment()//创建一个部署对象
		.name("流程定义")
		.addInputStream("ProcessInstanceTest.bpmn", ProcessInstanceBpmn)//使用资源文件的名称（与资源文件的名字一致）和输入流完成部署
		.addInputStream("ProcessInstanceTest.png", ProcessInstancePng)//使用资源文件的名称和输入流完成部署
		.deploy();
		
		System.out.println("部署ID："+deployment.getId());//
		System.out.println("部署名称："+deployment.getName());//
	}
	/**
	 * 启动流程实例
	 * 2
	 */
	@Test
	public void startProcessInstance(){
		//流程定义的key
		String processDefinitionKey = "processVariables";
		ProcessInstance pi = processEngine.getRuntimeService()//与正在执行的流程实例和执行对象相关的Service
						.startProcessInstanceByKey(processDefinitionKey);//使用流程定义的key启动流程实例，key对应helloworld.bpmn文件中id的属性值，使用key值启动，默认是按照最新版本的流程定义启动
		System.out.println("流程实例ID:"+pi.getId());//流程实例ID    101
		System.out.println("流程定义ID:"+pi.getProcessDefinitionId());//流程定义ID   helloworld:1:4
	}
	/**
	 * 设置流程变量
	 */
	@Test
	public void setProcessVariables(){
		TaskService taskService = processEngine.getTaskService();
		String taskId="1704";
		/**基本数据类型**/
//		taskService.setVariable(taskId, "请假天数", 3);
//		taskService.setVariable(taskId, "请假日期", new Date());
//		taskService.setVariable(taskId, "请假原因", "回家探亲");
		
		/**对象类型**/
		Persion p=new Persion();
		p.setId(taskId);
		p.setName("翠花");
		taskService.setVariable(taskId, "人员信息",p );
		System.out.println("任务变量设置完成");
	}
	/**
	 * 获取流程变量
	 */
	@Test
	public void getProcessVariables(){
		TaskService taskService = processEngine.getTaskService();
		String taskId="1704";
		/**基本数据类型**/
//		Integer day =(Integer) taskService.getVariable(taskId, "请假天数");
//		Date date =(Date) taskService.getVariable(taskId, "请假日期");
//		String resion = (String)taskService.getVariable(taskId, "请假原因");
//		System.out.println("请假天数: "+day);
//		System.out.println("请假日期: "+date);
//		System.out.println("请假原因: "+resion);
		
		/**对象类型**/
		Persion per =(Persion) taskService.getVariable(taskId, "人员信息");
		
		System.out.println("人员信息: "+per);
		
	}
	/**
	 * 模拟设置和获取流程变量的场景
	 */
	@Test
	public void setAndGetProcessVariables(){
		
		RuntimeService runtimeService = processEngine.getRuntimeService();//与正在执行的流程相关 
		
		TaskService taskService = processEngine.getTaskService();//与任务相关
		//@@@@设置流程变量
		//runtimeService.setVariable(excutionId, VariableName, value);//表示使用执行对象Id,和流程对象名称,设置流程变量的值(一次只能设置一个值)
		//runtimeService.setVariables(excutionId, map);//表示使用执行对象Id,和Map集合设置流程对象
		
		//taskService.setVariable(taskId, VariableName, value);//表示使用执行对象Id,和流程对象名称,设置流程变量的值(一次只能设置一个值)
		//taskService.setVariables(taskId, map);//表示使用执行对象Id,和Map集合设置流程对象
		
		/**启动流程和任务的实收设置流程变量**/
//		runtimeService.startProcessInstanceByKey(ProcessInstionKey, VariableName);//启动流程实例的同时,可以设置流程变量, VariableName使用map集合
//		taskService.complete(taskId, VariableName);//完成任务时,可以设置流程变量 ,VariableName使用map集合
		
		//@@@获取流程变量
		//runtimeService.getVariable(excutionId, VariableName);//表示使用执行对象Id,和流程对象名称获取流程变量的值
		//runtimeService.getVariables(excutionId);//表示使用执行对象Id,获取所有流程变量的值,将流程变量放到map中
		//runtimeService.getVariables(excutionId, VariableName);//使用执行对象Id,获取所有流程变量的值,将流程变量的名称放到集合中返回map
		
		//taskService.getVariable(taskId, VariableName);//表示使用任务Id,和流程对象名称获取流程变量的值
		//taskService.getVariables(taskId);//表示使用执行对象Id,获取所有流程变量的值,将流程变量放到map中
		//taskService.getVariables(taskId, VariableName);//使用执任务Id,获取所有流程变量的值,将流程变量的名称放到集合中返回map
	
	
	}
	/**
	 * 完成任务
	 */
	@Test
	public void completeMyPersonalTask(){
		//任务ID
		String taskId = "1402";
		processEngine.getTaskService()//与正在执行的任务管理相关的Service
					.complete(taskId);
		System.out.println("完成任务：任务ID："+taskId);
	}
	/**
	 *查询流程变量历史表
	 */
	@Test
	public void findProcessVarialbeHis(){
		
		List<HistoricVariableInstance> list = processEngine.getHistoryService()
						.createHistoricVariableInstanceQuery()//创建一个流程变量的历史查询
						.variableName("请假天数")
						.list();
		if(list.size()>0){
			for(HistoricVariableInstance hv:list){
				System.out.println("流程实例："+hv.getProcessInstanceId());
				System.out.println("变量id："+hv.getId());
				System.out.println("变量名称："+hv.getVariableName());
				System.out.println("任务id："+hv.getTaskId());
			}
		}
		
	}
}
